using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Athena
{
    public partial class Preferences : Form
    {
        public Preferences()
        {
            InitializeComponent();
        }

        private void Preferences_Load(object sender, EventArgs e)
        {
            ReadSettings();
        }       

        private void cmdOk_Click(object sender, EventArgs e)
        {
            ApplySettings();
            WriteSettings();
            Close();
        }
        private void cmdCancel_Click(object sender, EventArgs e)
        {
            ReadSettings();
            Close();
        }
        private void cmdApply_Click(object sender, EventArgs e)
        {
            ApplySettings();
            Close();
        }

        private static byte[] GetBytes(Hashtable table)
        {
            byte[] bytes;
            BinaryFormatter oFormatter = new BinaryFormatter();
            MemoryStream oStream = new MemoryStream();
            oFormatter.Serialize(oStream, table);
            bytes = oStream.GetBuffer();
            return bytes;
        }

        private void WriteSettings()
        {
            Application.UserAppDataRegistry.SetValue("AutoGenerateDegradation", chkAutoDegradation.Checked);
            Application.UserAppDataRegistry.SetValue("AutoGeneProduct", chkAutoGeneProduct.Checked);
            Application.UserAppDataRegistry.SetValue("ReactionLabels", chkReactionLabels.Checked);
            Application.UserAppDataRegistry.SetValue("ShowToolTip", chkToolTips.Checked);
            Application.UserAppDataRegistry.SetValue("MaxHistory", maxHistoryNum.Value.ToString());
            Application.UserAppDataRegistry.SetValue("MaxSimulationTime", maxSimulationNum.Value.ToString());

            Application.UserAppDataRegistry.SetValue("enabledGlyphs", 
                GetBytes(PluginManager.Instance.EnabledGlyphs), 
                Microsoft.Win32.RegistryValueKind.Binary);


            Application.UserAppDataRegistry.SetValue("enabledTools",
                            GetBytes(ToolManager.Instance.EnabledTools),
                            Microsoft.Win32.RegistryValueKind.Binary);



            /*Application.UserAppDataRegistry.SetValue("DefaultViewType", Objects.IDrawable.DEFAULT_VIEW.ToString());
            Application.UserAppDataRegistry.SetValue("SpeciesSizeH", Objects.SpeciesGlyph.INIT_SZ.Height.ToString());
            Application.UserAppDataRegistry.SetValue("SpeciesSizeW", Objects.SpeciesGlyph.INIT_SZ.Width.ToString());
            Application.UserAppDataRegistry.SetValue("PartSizeH", Objects.PartGlyph.INIT_SZ.Height.ToString());
            Application.UserAppDataRegistry.SetValue("PartSizeW", Objects.PartGlyph.INIT_SZ.Width.ToString());
             */ 
        }

        public static void InitializeSettings()
        {
            try
            {
                Program.Model.AutoDegradation = bool.Parse((string)Application.UserAppDataRegistry.GetValue("AutoGenerateDegradation", bool.TrueString));
                Program.Model.AutoGeneProduct = bool.Parse((string)Application.UserAppDataRegistry.GetValue("AutoGeneProduct", bool.TrueString));
                Objects.Connector.SHOW_LABEL = bool.Parse((string)Application.UserAppDataRegistry.GetValue("ReactionLabels", bool.TrueString));
                Utility.ShowToolTip = bool.Parse((string)Application.UserAppDataRegistry.GetValue("ShowToolTip", bool.TrueString));
                HistoryManager.MAX = int.Parse((string)Application.UserAppDataRegistry.GetValue("MaxHistory", "100"));
                ToolManager.MaxSimulationTime = int.Parse((string)Application.UserAppDataRegistry.GetValue("MaxSimulationTime", "1000"));

                PluginManager.Instance.EnabledGlyphs = ToHashTable((byte[])Application.UserAppDataRegistry.GetValue("enabledGlyphs", GetBytes(GetDefaultGlyphs())));
                ToolManager.Instance.EnabledTools = ToHashTable((byte[])Application.UserAppDataRegistry.GetValue("enabledTools", GetBytes(GetDefaultTools())));



                /*if (((string)Application.UserAppDataRegistry.GetValue("DefaultViewType", bool.TrueString)) == Objects.IDrawable.ViewType.Schematic.ToString())
                    Objects.IDrawable.DEFAULT_VIEW = Athena.Objects.IDrawable.ViewType.Schematic;
                else
                    Objects.IDrawable.DEFAULT_VIEW = Athena.Objects.IDrawable.ViewType.Block;
                Objects.SpeciesGlyph.INIT_SZ = new SizeF(float.Parse((string)Application.UserAppDataRegistry.GetValue("SpeciesSizeW", bool.TrueString)),
                                                      float.Parse((string)Application.UserAppDataRegistry.GetValue("SpeciesSizeH", bool.TrueString)));
                Objects.PartGlyph.INIT_SZ = new SizeF(float.Parse((string)Application.UserAppDataRegistry.GetValue("PartSizeW", bool.TrueString)),
                                                      float.Parse((string)Application.UserAppDataRegistry.GetValue("PartSizeH", bool.TrueString)));*/
            }
            catch (Exception)
            {
            }
        }

        private static Hashtable GetDefaultGlyphs()
        {
            return GetDefaultHashtable(PluginManager.Instance.AllGlyphs, true);
        }
        private static Hashtable GetDefaultTools()
        {
            return GetDefaultHashtable(ToolManager.Instance.AllToolNames, true);
        }

        private static Hashtable GetDefaultHashtable(List<string> keys, bool bValue)
        {            
            Hashtable oDefault = new Hashtable();
            foreach (string s in keys)
            {
                oDefault[s] = bValue;
            }
            return oDefault;
        }
        
        private static Hashtable ToHashTable(byte[] value)
        {
            BinaryFormatter oFormatter = new BinaryFormatter();
            MemoryStream oStream = new MemoryStream(value);
            Hashtable table = (System.Collections.Hashtable)oFormatter.Deserialize(oStream);
            return table;
        }

        private void ReadSettings()
        {
            try
            {
                chkAutoDegradation.Checked = bool.Parse((string)Application.UserAppDataRegistry.GetValue("AutoGenerateDegradation", bool.TrueString));
                chkAutoGeneProduct.Checked = bool.Parse((string)Application.UserAppDataRegistry.GetValue("AutoGeneProduct", bool.TrueString));
                chkReactionLabels.Checked = bool.Parse((string)Application.UserAppDataRegistry.GetValue("ReactionLabels", bool.TrueString));
                chkToolTips.Checked = bool.Parse((string)Application.UserAppDataRegistry.GetValue("ShowToolTip", bool.TrueString));
                HistoryManager.MAX = int.Parse((string)Application.UserAppDataRegistry.GetValue("MaxHistory", "100"));
                ToolManager.MaxSimulationTime = int.Parse((string)Application.UserAppDataRegistry.GetValue("MaxSimulationTime", "1000"));

                PluginManager.Instance.EnabledGlyphs = ToHashTable((byte[])Application.UserAppDataRegistry.GetValue("enabledGlyphs", GetBytes(GetDefaultGlyphs())));
                ToolManager.Instance.EnabledTools = ToHashTable((byte[])Application.UserAppDataRegistry.GetValue("enabledTools", GetBytes(GetDefaultTools())));

                UpdateGlyphCheckList();
                UpdateToolCheckList();
            }
            catch (Exception)
            {
            }
        }

        private void UpdateToolCheckList()
        {
            chkLstPlugins.Items.Clear();
            foreach (string s in ToolManager.Instance.AllToolNames)
            {
                if (ToolManager.Instance.EnabledTools.ContainsKey(s))
                    chkLstPlugins.Items.Add(s, (bool)ToolManager.Instance.EnabledTools[s]);
                else
                    chkLstPlugins.Items.Add(s, false);
            }
        }

        private void UpdateGlyphCheckList()
        {
            chkLstPalette.Items.Clear();
            foreach (string s in PluginManager.Instance.AllGlyphs)
            {
                if (PluginManager.Instance.EnabledGlyphs.ContainsKey(s))
                    chkLstPalette.Items.Add(s, (bool)PluginManager.Instance.EnabledGlyphs[s]);
                else
                    chkLstPalette.Items.Add(s, false);
            }
        }

        private void ApplySettings()
        {
            Program.Model.AutoDegradation = chkAutoDegradation.Checked;
            Program.Model.AutoGeneProduct = chkAutoGeneProduct.Checked;
            Objects.Connector.SHOW_LABEL = chkReactionLabels.Checked;
            Utility.ShowToolTip = chkToolTips.Checked;
            maxHistoryNum.Value = maxHistoryNum.Value;

            PluginManager.Instance.EnabledGlyphs.Clear();
            
            for (int i = 0; i < chkLstPalette.Items.Count; i++)
            {
                string sName = chkLstPalette.GetItemText(chkLstPalette.Items[i]);
                bool bValue = chkLstPalette.GetItemChecked(i);

                PluginManager.Instance.EnabledGlyphs[sName] = bValue;
            }

            ToolManager.Instance.EnabledTools.Clear();
            for (int i = 0; i < chkLstPlugins.Items.Count; i++)
            {
                string sName = chkLstPlugins.GetItemText(chkLstPlugins.Items[i]);
                bool bValue = chkLstPlugins.GetItemChecked(i);

                ToolManager.Instance.EnabledTools[sName] = bValue;
            }


            PluginManager.Instance.OnPluginsChanged();

        }

        private void Preferences_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Hide();
        }

        private void cmdContextAll_Click(object sender, EventArgs e)
        {
            SetAllItems(chkLstContextMenu, true);
        }

        private void cmdContextNone_Click(object sender, EventArgs e)
        {
            SetAllItems(chkLstContextMenu, false);
        }

        private void cmdPluginsAll_Click(object sender, EventArgs e)
        {
            SetAllItems(chkLstPlugins, true);
        }

        private void cmdPluginsNone_Click(object sender, EventArgs e)
        {
            SetAllItems(chkLstPlugins, false);
        }

        private static void SetAllItems(CheckedListBox listBox, bool bValue)
        {
            for (int i = 0; i < listBox.Items.Count; i++)
            {
                listBox.SetItemChecked(i, bValue);
            }
        }
        private void cmdPaletteAll_Click(object sender, EventArgs e)
        {            
            SetAllItems(chkLstPalette, true);
        }

        private void cmdPaletteNone_Click(object sender, EventArgs e)
        {
            SetAllItems(chkLstPalette, false);
        }

    }
}